/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package it.bbSimulator.Controller;

import it.bbSimulator.Model.Panels.Panel;
import it.bbSimulator.Model.Panels.PanelColor;
import it.bbSimulator.Model.Panels.PanelState;
import static it.bbSimulator.Model.Panels.PanelState.FINISHED;
import static it.bbSimulator.Model.Panels.PanelState.LOCKED;
import static it.bbSimulator.Model.Panels.PanelState.QUALIFIED;
import static it.bbSimulator.Model.Panels.PanelState.UNQUALIFIED;
import it.bbSimulator.Model.Panels.PanelType;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

/**
 *
 * @author Massimo
 */
public class PanelBank implements IPanelBank {

    ArrayList<Panel> pList;

    public PanelBank() {
        pList = new ArrayList<>();
    }

    /**
     * Load from save file
     *
     * @param file the file's URL
     */
    public PanelBank(String file) {
        pList = new ArrayList<>();
    }

    @Override
    public void AddPanel(Panel p) {
        pList.add(p);
    }

    @Override
    public ArrayList<Panel> getFilteredPanels(PanelColor color) {
        Iterator<Panel> i = pList.iterator();
        ArrayList<Panel> retList = new ArrayList<>();
        while (i.hasNext()) {
            Panel p = i.next();
            if (p.getPanelColor() == color) {
                retList.add(p);
            }
        }
        return retList;
    }

    @Override
    public ArrayList<Panel> getFilteredPanels(PanelColor color, PanelState state, Date refDate) {
        Iterator<Panel> i = pList.iterator();
        ArrayList<Panel> retList = new ArrayList<>();
        while (i.hasNext()) {
            Panel p = i.next();
            if (p.getPanelColor() == color) {
                switch (state) {
                    case QUALIFIED:
                        if ((p.getQualifyDate() != null && p.getQualifyDate().compareTo(refDate) < 0) && (p.getDeadlineDate() == null || p.getDeadlineDate().compareTo(refDate) > 0)) {
                            retList.add(p);
                        }
                        break;
                    case UNQUALIFIED:
                        if ((p.getPurchaseDate() != null && p.getPurchaseDate().compareTo(refDate) < 0) && (p.getQualifyDate() == null || p.getQualifyDate().compareTo(refDate) > 0) && (p.getLockDate() == null || p.getLockDate().compareTo(refDate) > 0)) {
                            retList.add(p);
                        }
                        break;
                    case :

                        break;
                    case FINISHED:
                        if (p.getDeadlineDate().compareTo(refDate) < 0) {
                            retList.add(p);
                        }
                        break;
                }
            }
        }
        return retList;
    }

    private boolean removePanel(PanelColor c, PanelState s, Date refDate) {
        Iterator<Panel> i = pList.iterator();
        while (i.hasNext()) {
            Panel p = i.next();
            if (p.getPanelColor() == c && p.getState(refDate) == s) {
                return pList.remove(p);
            }
        }
        return false;
    }

    @Override
    public boolean rollup(PanelColor color, int n, Date refDate) throws RollUpExeption {
        if (n % 3 != 0) {
            throw new RollUpExeption("Non è multiplo di 3");
        }
        if (color == PanelColor.Prestige) {
            throw new RollUpExeption("Non è possibile eseguire rollup di questo pannello");
        }
        int locked = this.getFilteredPanels(color, LOCKED, refDate).size();
        int unqualified = this.getFilteredPanels(color, UNQUALIFIED, refDate).size();
        if (locked + unqualified < n) {
            throw new RollUpExeption("Non ci sono abbastanza pannelli");
        }
        //firt remove unqualified panels
        for (int i = 0; i < unqualified && i < n; i++) {
            removePanel(color, LOCKED, refDate);
        }
        //if they not enouth, remove locked panels
        for (int i = 0; i < locked && unqualified + i < n; i++) {
            removePanel(color, LOCKED, refDate);
        }
        switch (color) {
            case Yellow:
                for (int i = 0; i < n / 3; i++) {
                    this.AddPanel(new Panel(PanelColor.Purple, PanelType.ROLLUP));
                }
                break;
            case Purple:
                for (int i = 0; i < n / 3; i++) {
                    this.AddPanel(new Panel(PanelColor.Blue, PanelType.ROLLUP));
                }
                break;
            case Blue:
                for (int i = 0; i < n / 3; i++) {
                    this.AddPanel(new Panel(PanelColor.Green, PanelType.ROLLUP));
                }
                break;
            case Green:
                for (int i = 0; i < n / 3; i++) {
                    this.AddPanel(new Panel(PanelColor.Red, PanelType.ROLLUP));
                }
                break;
            case Red:
                for (int i = 0; i < n / 3; i++) {
                    this.AddPanel(new Panel(PanelColor.Black, PanelType.ROLLUP));
                }
                break;
            case Black:
                for (int i = 0; i < n / 3; i++) {
                    this.AddPanel(new Panel(PanelColor.Prestige, PanelType.ROLLUP));
                }
                break;
        }
        return true;
    }
}
